package com.meshnetics.gb.stack.core.event;

import com.meshnetics.gb.Context;
import com.meshnetics.gb.event.Event;
import com.meshnetics.gb.stack.core.layer.StackLayer;
import com.meshnetics.gb.util.ToStringUtil;

/**
 * Base class for all StackEvents.
 *
 * @author mmarkov
 */
public class StackEvent extends Event {
    /**
     * Integer identifier for the event. It's usually unique within one StackLayer.
     */
    protected int id = Integer.MIN_VALUE;

    /**
     * Source of the event.
     */
    protected final StackLayer source;

    /**
     * Constructs StackEvent having the given name and type and no Context.
     *
     * @param name the name of StackEvent
     * @param type the type of StackEvent
     */
    public StackEvent(String name, StackEventType type) {
        this(name, type, null);
    }

    /**
     * Constructs StackEvent having the given name, type and context.
     *
     * @param name the name of StackEvent
     * @param type the type of StackEvent
     * @param ctx  the Context of StackEvent (could be null)
     */
    public StackEvent(String name, StackEventType type, Context ctx) {
        this(name, type, ctx, null);
    }

    /**
     * Creates StackEvent with given name, type, context and source.
     *
     * @param name   the name of StackEvent
     * @param type   the type of StackEvent
     * @param ctx    the Context of StackEvent (could be null)
     * @param source the source of event (can be null)
     */
    public StackEvent(String name, StackEventType type, Context ctx, StackLayer source) {
        super(name, type, ctx);
        this.source = source;
    }

    /**
     * Returns source of this event.
     *
     * @return source of this event
     */
    public StackLayer getSource() {
        return source;
    }

    /**
     * Sets the context for the event to the given value.
     *
     * @param ctx Context to be set
     */
    public void setContext(Context ctx) {
        this.ctx = ctx;
    }

    /**
     * Sets the ID for the event.
     *
     * @param id new value of the id
     */
    public void setID(int id) {
        this.id = id;
    }

    /**
     * Sets the ID for the event.
     *
     * @param id new value of the id
     */
    public void setID(Integer id) {
        this.id = id.intValue();
    }

    /**
     * Returns the ID for the event.
     *
     * @return the ID for the event
     */
    public int getID() {
        return id;
    }

    /**
     * Returns a string representation of this Event.
     *
     * @return a string representation of this Event
     */
    public String toString() {
        return "[" + super.toString() + ", id: " + ToStringUtil.toHexString(id) + "]";
    }
}
